home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 25
/
Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso
/
Aminet
/
game
/
shoot
/
ADoom_src_1_2.lha
/
ADoom_src
/
amiga_plane.s
< prev
next >
Wrap
Text File
|
1998-02-28
|
16KB
|
738 lines
mc68020
xdef @R_MakeSpans
xdef _R_MakeSpans
xdef @R_DrawPlanes
xdef _R_DrawPlanes
xdef @R_MapPlane
xdef _R_MapPlane
section text,code
near a4,-2
;-----------------------------------------------------------------------
; R_MakeSpans (in r_plane.c) by Arto Huusko <arto.huusko@pp.qnet.fi>
xref _spanstart
;;; xref @R_MapPlane
;void
;__asm R_MakeSpans
;( register __d2 int x,
; register __d3 int t1,
; register __d4 int b1,
; register __d5 int t2,
; register __d6 int b2 );
cnop 0,4
@R_MakeSpans:
_R_MakeSpans:
;First comments are for the non-__asm version of func prototype
; movem.l d2-d7/a2/a3,-(sp)
movem.l d3-d7/a2/a3,-(sp)
; move.l 36(sp),d4 ;(rest of args come in stack) int b1
; move.l d0,d2 ;int x
; move.l 40(sp),d5 ;int t2
; move.l d1,d3 ;int t1
; move.l 44(sp),d6 ;int b2
;;; move.l #_spanstart,a2
movea.l _spanstart(a4),a2
move.l d2,-(sp)
subq.l #1,(sp) ;x-1, for R_MapPlane (third argument, thus in stack)
;D2=X D3=T1 D4=B1 D5=T2 D6=B2, (sp)=X-1
;prepare while(t1 < t2 && t1<=b1)
;Calculate just how many times the loop is done, so no need
; to compare everytime
move.l d5,d7
sub.l d3,d7
ble.b .rmsl1_Done ;T1=>T2, therefore loop not done
subq.l #1,d7
move.l d4,d0
sub.l d3,d0
;If T1>B1 first loop is not done. The same rule also applies to
;second loop (first: t1<=b1 second: b1>=t1) so we skip both loops.
bmi.b .rmsl2_Done
lea (a2,d3.l*4),a3
cmp.l d0,d7 ;Do the loop until the smaller delta is zero
;smaller because of AND operation in while statement
bmi.b .rms_Loop1
move.l d0,d7 ;t1<=b1 effective
.rms_Loop1_2: ;Another loop...
move.l (a3)+,d1
move.l d3,d0
jsr (@R_MapPlane)
addq.l #1,d3
dbf d7,.rms_Loop1_2
bra.b .rmsl2_Done ;..so we can quickly skip
;loop #2. The loop was done with t1<=b1 and in the
;end this is not true. Also loop 2 uses the same comparison
;it is automatically false thus we can skip it.
cnop 0,4
.rms_Loop1:
move.l (a3)+,d1
move.l d3,d0
jsr (@R_MapPlane)
addq.l #1,d3
dbf d7,.rms_Loop1
.rmsl1_Done:
move.l d4,d0
sub.l d3,d0
bmi.b .rmsl2_Done
move.l d4,d7
sub.l d6,d7
ble.b .rmsl2_Done
subq.l #1,d7
lea 4(a2,d4.l*4),a3
cmp.l d0,d7
bmi.b .rms_Loop2
move.l d0,d7 ;b1>=t1 effective
.rms_Loop2_2:
move.l -(a3),d1
move.l d4,d0
jsr (@R_MapPlane)
subq.l #1,d4
dbf d7,.rms_Loop2_2
move.l d3,d7
sub.l d5,d7
bhi.b .rms_DoL3
bra.w .rmsl4_Done
cnop 0,4
.rms_Loop2:
move.l -(a3),d1
move.l d4,d0
jsr (@R_MapPlane)
subq.l #1,d4
dbf d7,.rms_Loop2
.rmsl2_Done:
;The following copy loops (spanstart[??]=x;) are optimised
;by assuming that the loop is executed several (more then four) times
move.l d3,d7
sub.l d5,d7
ble.b .rmsl3_Done
.rms_DoL3:
subq.l #1,d7
move.l d6,d0
sub.l d5,d0
bmi.w .rmsl4_Done
lea (a2,d5.l*4),a3
cmp.l d0,d7
bmi.b .rms_StartLoop3
move.l d2,(a3)+
bclr #0,d0
beq.b .rmsl32_Pass1
move.l d2,(a3)+
.rmsl32_Pass1:
bclr #1,d0
beq.b .rmsl32_Pass2
move.l d2,(a3)+
move.l d2,(a3)+
.rmsl32_Pass2:
tst.l d0
beq.b .rmsl4_Done
.rms_Loop3_2:
move.l d2,(a3)+
move.l d2,(a3)+
move.l d2,(a3)+
move.l d2,(a3)+
subq.l #4,d0
bgt.b .rms_Loop3_2
bra.b .rmsl4_Done
cnop 0,4
.rms_StartLoop3:
move.l d2,(a3)+ ;always at least once
bclr #0,d7
beq.b .rmsl3_Pass1
move.l d2,(a3)+
.rmsl3_Pass1:
bclr #1,d7
beq.b .rmsl3_Pass2
move.l d2,(a3)+
move.l d2,(a3)+
.rmsl3_Pass2:
tst.l d7
beq.b .rmsl3_Done
.rms_Loop3:
move.l d2,(a3)+
move.l d2,(a3)+
move.l d2,(a3)+
move.l d2,(a3)+
addq.l #4,d5 ;saves for addq per loop
subq.l #4,d7 ;also saves four dbfs, though adds here...
bgt.b .rms_Loop3
.rmsl3_Done:
move.l d6,d0
sub.l d5,d0
bmi.b .rmsl4_Done
move.l d6,d7
sub.l d4,d7
ble.b .rmsl4_Done
subq.l #1,d7
lea 4(a2,d6.l*4),a3
cmp.l d0,d7
bmi.b .rms_StartLoop4
move.l d0,d7
.rms_StartLoop4:
move.l d2,-(a3) ;always at least once
bclr #0,d7
beq.b .rmsl4_Pass1
move.l d2,-(a3)
.rmsl4_Pass1:
bclr #1,d7
beq.b .rmsl4_Pass2
move.l d2,-(a3)
move.l d2,-(a3)
.rmsl4_Pass2:
tst.l d7
beq.b .rmsl4_Done
.rms_Loop4:
move.l d2,-(a3)
move.l d2,-(a3)
move.l d2,-(a3)
move.l d2,-(a3)
subq.l #4,d7
bgt.b .rms_Loop4
.rmsl4_Done:
addq.l #4,sp
movem.l (sp)+,d3-d7/a2/a3
; movem.l (sp)+,d2-d7/a2/a3
rts
;void R_MakeSpans(int x, int t1, int b1, int t2, int b2)
;{
;
; while (t1 < t2 && t1<=b1)
; {
; R_MapPlane (t1,spanstart[t1],x-1);
; t1++;
; }
; while (b1 > b2 && b1>=t1)
; {
; R_MapPlane (b1,spanstart[b1],x-1);
; b1--;
; }
;
; while (t2 < t1 && t2<=b2)
; {
; spanstart[t2] = x;
; t2++;
; }
; while (b2 > b1 && b2>=t2)
; {
; spanstart[b2] = x;
; b2--;
; }
;}
;-----------------------------------------------------------------------
; R_DrawPlanes (in r_plane.c) by Arto Huusko <arto.huusko@pp.qnet.fi>
; STRUCTURE visplane,0
;
; LONG height
; LONG picnum
; LONG lightlevel
; LONG minx
; LONG maxx
; PTR top
; PTR bottom
;
; LABEL visplane_size
height equ 0 ; fixed
picnum equ 4 ; int
lightlevel equ 8 ; int
minx equ 12 ; int
maxx equ 16 ; int
top equ 20 ; unsigned short* ([-1..SCREENWIDTH])
bottom equ 24 ; unsigned short* ([-1..SCREENWIDTH])
visplane_size equ 28
xref _visplanes ; FAR visplane_t[]
xref _skyflatnum ; int
xref _flattranslation ; int*
xref _firstflat ; int
xref _viewz ; fixed_t
xref _planeheight ; fixed_t
xref _zlight ; FAR lighttable_t *[LIGHTLEVELS][MAXLIGHTZ]
xref _planezlight ; lighttable_t**
xref _extralight ; int
xref _lastvisplane ; visplane_t*
;;; xref _pspriteiscale ; fixed_t
xref _pspriteiscale2 ; fixed_t
xref _detailshift ; int
xref _skytexturemid ; int
xref _viewangle ; angle_t
xref _skytexture ; int
xref _ds_source
xref _colormaps
xref _dc_colormap
xref _dc_iscale
xref _dc_texturemid
xref _xtoviewangle ; angle_t *
xref _dc_x
xref _dc_yl
xref _dc_yh
xref _dc_source
xref _colfunc
xref @W_CacheLumpNum
xref @Z_ChangeTag2
xref @R_GetColumn
cnop 0,4
@R_DrawPlanes:
_R_DrawPlanes:
movem.l d2-d7/a2/a3/a5/a6,-(sp)
move.l #_visplanes,a2
.rd_Loop:
move.l minx(a2),d2
move.l maxx(a2),d3 ;These ones are used later, too
cmp.l d2,d3
bmi.w .rd_Next ;minx>maxx -> next loop
;;; move.l a2,a3
;;; add.l d2,a3 ; a3 -> pl + minx
;;; move.l a3,a5 ; a5 -> pl + minx
;;; add.l #top,a3 ; a3 -> pl + minx + top
;;; add.l #bottom-1,a5 ; a5 -> pl + minx + bottom - 1
movea.l top(a2),a3
lea (a3,d2.l*2),a3 ; a3 -> pl->top[minx]
movea.l bottom(a2),a5
lea -2(a5,d2.l*2),a5 ; a5 -> pl->bottom[minx-1]
move.l picnum(a2),d1 ; used if not sky...
cmp.l _skyflatnum(a4),d1
beq.w .rdl_Sky
move.l _flattranslation(a4),a0
move.l _firstflat(a4),d0
add.l (a0,d1.l*4),d0 ; D1 contains picnum, A0 array of ints
moveq #1,d1 ; PU_STATIC
jsr (@W_CacheLumpNum)
move.l d0,_ds_source(a4)
move.l height(a2),d0
sub.l _viewz(a4),d0
bpl.b .rdl_HP ; These two lines are equal to
neg.l d0 ; abs() or iabs(). Branch if =>0, otherwise switch sign
.rdl_HP:
move.l d0,_planeheight(a4)
move.l lightlevel(a2),d0
lsr.l #4,d0 ;LIGHTSEGSHIFT
move.l #_zlight,_planezlight(a4)
add.l _extralight(a4),d0
cmp.l #0,d0
bmi.b .rdl_LightDone ; lightlevel 0, no need to change _planezlight anymore
cmp.l #16,d0 ; 16=LIGHTLEVELS
bmi.b .rdl_LightOK
add.l #7680,_planezlight(a4) ;15<<9 ((15<<7)*4)
bra.b .rdl_LightDone
.rdl_LightOK:
lsl.l #8,d0
add.l d0,d0
add.l d0,_planezlight(a4)
.rdl_LightDone:
;;; move.b #$FF,top+1(a2,d3.l) ;D3=maxx, top+1 ->top[maxx+1]
;;; move.b #$FF,-(a3)
movea.l top(a2),a0
move.w #$FFFF,2(a0,d3.l*2) ;D3=maxx, top+1 ->top[maxx+1]
move.w #$FFFF,-(a3)
;x=pl->minx=d2
move.l d3,d7
sub.l d2,d7
addq.l #1,d7 ;d7 = x<=stop
moveq #0,d3
moveq #0,d4
moveq #0,d5
moveq #0,d6
.rdl_MSLoop:
;;; move.b (a3)+,d3 ; bumps to top[x] at the same time!
;;; move.b (a3),d5
;;; move.b (a5)+,d4
;;; move.b (a5),d6
move.w (a3)+,d3 ; bumps to top[x] at the same time!
move.w (a3),d5
move.w (a5)+,d4
move.w (a5),d6
jsr (@R_MakeSpans) ; passes d2/d3/d4/d5/d6
addq.l #1,d2
dbf d7,.rdl_MSLoop
move.l _ds_source(a4),a0
moveq #101,d0 ; PU_STATIC
jsr (@Z_ChangeTag2)
.rd_Next:
add.l #visplane_size,a2
cmp.l _lastvisplane(a4),a2 ; pl<lastvisplane
bmi.w .rd_Loop
movem.l (sp)+,d2-d7/a2/a3/a5/a6
rts
cnop 0,4
.rdl_Sky:
;;; move.l _pspriteiscale(a4),d0
;;; move.l _detailshift(a4),d1
;;; asr.l d1,d0
move.l _pspriteiscale2(a4),d0
move.l _colormaps(a4),_dc_colormap(a4)
move.l d0,_dc_iscale(a4)
move.l _skytexturemid(a4),_dc_texturemid(a4)
sub.l d2,d3 ; maxx-minx == maxx-x, how many till x>maxx
moveq #0,d5
moveq #0,d6
;;; lea _xtoviewangle(a4),a6
movea.l _xtoviewangle(a4),a6
lea (a6,d2.l*4),a6 ; a6 -> xtoviewangle[minx]
moveq #22,d7 ; ANGLETOSKYSHIFT
move.l d2,_dc_x(a4) ; dc_x = minx
;;; addq.l #1,a5
addq.l #2,a5 ; a5 -> pl->bottom[minx]
.rdl_SkyLoop:
;;; move.b (a3)+,d5
;;; move.b (a5)+,d6
move.w (a3)+,d5 ; dc_yl = pl->top[x]
move.w (a5)+,d6 ; dc_yh = pl->bottom[x]
move.l d5,_dc_yl(a4)
move.l d6,_dc_yh(a4)
move.l (a6)+,d1 ; To keep values consistent if not drawn
; the next 2 lines may be unnecessary --- but who knows?
cmp.l d5,d6
bmi.b .rdlsl_Next ; needless? I think so...
add.l _viewangle(a4),d1 ; viewangle + xtoviewangle[x]
move.l _skytexture(a4),d0
asr.l d7,d1 ; angle
jsr (@R_GetColumn) ; R_GetColumn(skytexture,angle)
move.l d0,_dc_source(a4)
move.l _colfunc(a4),a0
jsr (a0)
.rdlsl_Next:
addq.l #1,_dc_x(a4) ; dc_x = x
dbf d3,.rdl_SkyLoop
bra.b .rd_Next
; void R_DrawPlanes (void)
; {
; visplane_t* pl;
; int light;
; int x;
; int stop;
; int angle;
;
; for (pl = visplanes ; pl < lastvisplane ; pl++)
; {
; if (pl->minx > pl->maxx)
; continue;
;
;
; // sky flat
; if (pl->picnum == skyflatnum)
; {
; dc_iscale = pspriteiscale2/*>>detailshift*/;
;
; // Sky is allways drawn full bright,
; // i.e. colormaps[0] is used.
; // Because of this hack, sky is not affected
; // by INVUL inverse mapping.
; dc_colormap = colormaps;
; dc_texturemid = skytexturemid;
; for (x=pl->minx ; x <= pl->maxx ; x++)
; {
; dc_yl = pl->top[x];
; dc_yh = pl->bottom[x];
;
; if (dc_yl <= dc_yh)
; {
; angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
; dc_x = x;
; dc_source = R_GetColumn(skytexture, angle);
; colfunc ();
; }
; }
; continue;
; }
;
; // regular flat
; ds_source = W_CacheLumpNum(firstflat +
; flattranslation[pl->picnum],
; PU_STATIC);
;
; planeheight = iabs(pl->height-viewz);
; light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
;
; if (light >= LIGHTLEVELS)
; light = LIGHTLEVELS-1;
;
; if (light < 0)
; light = 0;
;
; planezlight = zlight[light];
;
; //pl->top[pl->maxx+1] = 0xff;
; //pl->top[pl->minx-1] = 0xff;
; pl->top[pl->maxx+1] = 0xffff;
; pl->top[pl->minx-1] = 0xffff;
;
; stop = pl->maxx + 1;
;
; for (x=pl->minx ; x<= stop ; x++)
; {
; R_MakeSpans(x,pl->top[x-1],
; pl->bottom[x-1],
; pl->top[x],
; pl->bottom[x]);
; }
;
; Z_ChangeTag (ds_source, PU_CACHE);
; }
; }
;-----------------------------------------------------------------------
; R_MapPlane (in r_plane.c) by Arto Huusko <arto.huusko@pp.qnet.fi>
xref _cachedheight ;fixed_t*
xref _cacheddistance ;fixed_t*
xref _yslope ;fixed_t*
xref _cachedxstep ;fixed_t*
xref _cachedystep ;fixed_t*
xref _basexscale ;fixed_t
xref _baseyscale ;fixed_t
xref _distscale ;fixed_t*
xref _viewx ;fixed_t
xref _viewy ;fixed_t
xref _finecosine ;fixed_t*
xref _finesine ;FAR int []
xref _fixedcolormap ;lighttable_t*
xref _ds_xstep
xref _ds_ystep
xref _ds_x1
xref _ds_x2
xref _ds_y
xref _ds_xfrac
xref _ds_yfrac
xref _ds_colormap
xref _spanfunc
xref _FixedMul
MAXLIGHTZ equ 128
LIGHTZSHIFT equ 20
ANGLETOFINESHIFT equ 19
;void
;R_MapPlane
;( int y,
; int x1,
; int x2 )
cnop 0,4
@R_MapPlane:
_R_MapPlane:
movem.l d3/d4/d7,-(sp)
move.l d0,d3 ;Y
move.l d1,d4 ;X1
move.l _FixedMul(a4),a1 ;Prepare function. amiga_fixed.s does not use A1!
move.l _planeheight(a4),d0 ;ready for cache...
;;; move.l #_cachedheight,a0
movea.l _cachedheight(a4),a0
cmp.l (a0,d3.l*4),d0
beq.b .rm_If2 ;ah, we are cached!
move.l d0,(a0,d3.l*4)
;;; move.l #_yslope,a0
movea.l _yslope(a4),a0
move.l (a0,d3.l*4),d1
jsr (a1)
move.l d0,d7 ;save distance
;;; move.l #_cacheddistance,a0
movea.l _cacheddistance(a4),a0
move.l d0,(a0,d3.l*4)
move.l _basexscale(a4),d1
jsr (a1)
move.l d0,_ds_xstep(a4)
;;; move.l #_cachedxstep,a0
movea.l _cachedxstep(a4),a0
move.l d0,(a0,d3.l*4)
move.l _baseyscale(a4),d1
move.l d7,d0
jsr (a1)
move.l d0,_ds_ystep(a4)
;;; move.l #_cachedystep,a0
movea.l _cachedystep(a4),a0
move.l d0,(a0,d3.l*4)
bra.b .rm_1Done
.rm_If2:
;;; move.l #_cacheddistance,a0
movea.l _cacheddistance(a4),a0
move.l (a0,d3.l*4),d7
;;; move.l #_cachedxstep,a0
movea.l _cachedxstep(a4),a0
move.l (a0,d3.l*4),_ds_xstep(a4)
;;; move.l #_cachedystep,a0
movea.l _cachedystep(a4),a0
move.l (a0,d3.l*4),_ds_ystep(a4)
.rm_1Done:
move.l d3,_ds_y(a4)
move.l d4,_ds_x1(a4)
move.l d7,d0
;;; move.l #_distscale,a0
movea.l _distscale(a4),a0
move.l (a0,d4.l*4),d1
jsr (a1)
move.l d0,d3 ;Y not needed anymore
;;; lea _xtoviewangle(a4),a0
movea.l _xtoviewangle(a4),a0
move.l (a0,d4.l*4),d4 ;x1 not needed anymore
add.l _viewangle(a4),d4
moveq #ANGLETOFINESHIFT,d1
lsr.l d1,d4
move.l _finecosine(a4),a0
move.l (a0,d4.l*4),d0
move.l d3,d1
jsr (a1)
move.l _viewx(a4),_ds_xfrac(a4)
add.l d0,_ds_xfrac(a4)
move.l #_finesine,a0
move.l (a0,d4.l*4),d0
move.l d3,d1
jsr (a1)
move.l _viewy(a4),d1
neg.l d1
move.l d1,_ds_yfrac(a4)
sub.l d0,_ds_yfrac(a4)
move.l _fixedcolormap(a4),d0
bne.b .rm_FixedCMAP
moveq #LIGHTZSHIFT,d0
lsr.l d0,d7
cmp.l #MAXLIGHTZ,d7
bmi.b .rm_D7OK
move.l #MAXLIGHTZ-1,d7
.rm_D7OK:
move.l _planezlight(a4),a0
move.l (a0,d7.l*4),_ds_colormap(a4)
.rm_CMAPDone:
move.l 16(sp),_ds_x2(a4)
move.l _spanfunc(a4),a0
jsr (a0)
movem.l (sp)+,d3/d4/d7
rts
cnop 0,4
.rm_FixedCMAP:
move.l d0,_ds_colormap(a4)
bra.b .rm_CMAPDone
;void
;R_MapPlane
;( int y,
; int x1,
; int x2 )
;{
; angle_t angle;
; fixed_t distance;
; fixed_t length;
; unsigned index;
;
; if (planeheight != cachedheight[y])
; {
; cachedheight[y] = planeheight;
; distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]);
; ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale);
; ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale);
; }
; else
; {
; distance = cacheddistance[y];
; ds_xstep = cachedxstep[y];
; ds_ystep = cachedystep[y];
; }
;
; length = FixedMul (distance,distscale[x1]);
; angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
; ds_xfrac = viewx + FixedMul(finecosine[angle], length);
; ds_yfrac = -viewy - FixedMul(finesine[angle], length);
;
; if (fixedcolormap)
; ds_colormap = fixedcolormap;
; else
; {
; index = distance >> LIGHTZSHIFT;
;
; if (index >= MAXLIGHTZ )
; index = MAXLIGHTZ-1;
;
; ds_colormap = planezlight[index];
; }
;
; ds_y = y;
; ds_x1 = x1;
; ds_x2 = x2;
;
; // high or low detail
; spanfunc ();
;}
;-----------------------------------------------------------------------
end